import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
from statistics import mean
import os
from sklearn.preprocessing import MinMaxScaler
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, LSTM
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression
def scale_split(df):
scaler = MinMaxScaler()
numerical_columns = df.select_dtypes(include='number').columns
#print(numerical_columns)
scaled_df = df.copy()
# positions = list(set(df['Pos']))
# for role in positions:
# role_data = df[df['Pos'] == role]
# scaled_df.loc[scaled_df['Pos'] == role, numerical_columns] = scaler.fit_transform(role_data[numerical_columns])
scaled_df[numerical_columns] = scaler.fit_transform(df[numerical_columns])
non_numeric_columns = df.select_dtypes(exclude='number').columns
#print(non_numeric_columns)
scaled_df[non_numeric_columns] = df[non_numeric_columns]
return scaled_df
# directory containing the files
og_dir = 'c:\\Users\\advai\\College Semesters\\22-23 Win\\data-driven analysis of LCK\\Testing'
directory = os.path.join(og_dir, 'secret_regions_test')
models_directory = os.path.join(og_dir, 'model_files')
os.chdir(directory)
positions = ["Top", "Jungle", "Middle", "ADC", "Support"]
relevant_cols = [['K', 'A', 'KDA', 'KP', 'KS%', 'GD10', 'CSPM', 'DMG%', 'GOLD%', 'WPM'],
['K', 'A', 'KDA', 'KP', 'KS%', 'DTH%', 'GD10', 'CSPM', 'WPM', 'WCPM'],
['K', 'D', 'A', 'KDA', 'KS%', 'DTH%', 'GD10', 'CSPM', 'DMG%', 'WPM'],
['K', 'D', 'A', 'KP', 'CSD10', 'DMG%', 'GOLD%', 'WPM', 'CWPM', 'WCPM'],
['K', 'D', 'A', 'KDA', 'KS%', 'CSPM', 'DMG%', 'GOLD%', 'WPM', 'CWPM']]
for role in positions:
print("for", role)
print(relevant_cols[positions.index(role)])
for Top ['K', 'A', 'KDA', 'KP', 'KS%', 'GD10', 'CSPM', 'DMG%', 'GOLD%', 'WPM'] for Jungle ['K', 'A', 'KDA', 'KP', 'KS%', 'DTH%', 'GD10', 'CSPM', 'WPM', 'WCPM'] for Middle ['K', 'D', 'A', 'KDA', 'KS%', 'DTH%', 'GD10', 'CSPM', 'DMG%', 'WPM'] for ADC ['K', 'D', 'A', 'KP', 'CSD10', 'DMG%', 'GOLD%', 'WPM', 'CWPM', 'WCPM'] for Support ['K', 'D', 'A', 'KDA', 'KS%', 'CSPM', 'DMG%', 'GOLD%', 'WPM', 'CWPM']
We now use this ensemble model as the final piece of our rankings. We will take the ranking achieved from this, and the ranking achieved from raw %ile in each of the important stats for a given role, to create a final ranking for players by their respective role
# now ranking the Spring 2023 roster data
os.chdir(os.path.join(og_dir, "secret_regions_test"))
player_data = pd.read_csv('LEC 2022 Spring.csv')
mvp_data = pd.read_csv('lec_mvp.csv')
os.chdir(os.path.join(og_dir, "model_files"))
# create a new column called "MVP" in the player_data dataframe
player_data["MVP"] = 0
# iterate over each row in the MVP data dataframe
for index, row in mvp_data.iterrows():
# check if the player's name exists in the player_data dataframe
if row["Player"] in player_data["Player"].values:
# if so, find the row with the player's name and update the "MVP" column with the MVP points
player_data.loc[player_data["Player"] == row["Player"], "MVP"] = row["Points"]
player_data['Year'] = "2023"
player_data['Season'] = "Spring"
exclude = ['Player', 'Team', 'Pos', 'Year', 'Season']
incldue = [col for col in player_data.columns if col not in exclude]
for cols in incldue:
for idx, val in player_data[cols].items():
if str(val).endswith("%"):
player_data.at[idx, cols] = str(val.strip("%"))
player_data[incldue] = player_data[incldue].astype('float64')
rank_test = scale_split(player_data)
rank_test = rank_test.dropna(axis=1)
rank_test_vals = rank_test.select_dtypes(include='number')
rank_test_vals = rank_test_vals.drop(['GP', 'MVP'], axis=1)
rank_test_labels = rank_test.select_dtypes(exclude='number')
rank_test_labels = pd.concat([rank_test_labels, rank_test[['GP', 'MVP']]], axis=1)
role_rank_test = []
role_rank_test_labels = []
role_rank_test_vals = []
# generating 5 sets of data for players in each role
for position in positions:
role_rank_test.append(rank_test[rank_test['Pos'] == position])
role_rank_test_labels.append(rank_test_labels[rank_test_labels['Pos'] == position])
role_rank_test_vals.append(rank_test_vals[rank_test_labels['Pos'] == position])
role_rank_test[positions.index("ADC")].sort_values(by=['KDA', 'W%', 'DMG%'], ascending=False).head()
| Player | Team | Pos | GP | W% | CTR% | K | D | A | KDA | ... | D%P15 | EGPM | GOLD% | STL | WPM | CWPM | WCPM | MVP | Year | Season | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 45 | Upset | Fnatic | ADC | 1.0 | 0.901639 | 0.576923 | 0.812500 | 0.000000 | 0.377622 | 1.000000 | ... | 0.856618 | 0.908046 | 0.878641 | 0.00 | 0.120253 | 0.103448 | 0.473684 | 0.1 | 2023 | Spring |
| 8 | Comp | Rogue | ADC | 1.0 | 1.000000 | 0.461538 | 0.906250 | 0.268657 | 0.398601 | 0.337838 | ... | 0.860294 | 1.000000 | 0.966019 | 0.00 | 0.126582 | 0.172414 | 0.526316 | 0.4 | 2023 | Spring |
| 12 | Flakked | G2 Esports | ADC | 1.0 | 0.721311 | 0.461538 | 0.687500 | 0.313433 | 0.307692 | 0.222973 | ... | 0.941176 | 0.835249 | 0.873786 | 0.00 | 0.107595 | 0.137931 | 0.578947 | 0.1 | 2023 | Spring |
| 44 | UNF0RGIVEN | MAD Lions | ADC | 1.0 | 0.442623 | 0.903846 | 0.843750 | 0.402985 | 0.293706 | 0.195946 | ... | 0.941176 | 0.873563 | 0.932039 | 0.00 | 0.018987 | 0.051724 | 0.289474 | 0.1 | 2023 | Spring |
| 18 | Jezu | SK Gaming | ADC | 1.0 | 0.360656 | 0.692308 | 0.729167 | 0.373134 | 0.160839 | 0.155405 | ... | 0.856618 | 0.747126 | 0.878641 | 0.25 | 0.075949 | 0.189655 | 0.394737 | 0.2 | 2023 | Spring |
5 rows × 31 columns
def rankings(role_rank_test, relevant_cols, positions):
ranks = {}
for role in positions:
# print(role)
relevant = relevant_cols[positions.index(role)]
# print(relevant)
rankings_dict = {}
temp_data = role_rank_test[positions.index(role)]
for player in temp_data["Player"]:
player_rankings = []
for col in list(relevant):
# print(col, "\n")
sorted_data = temp_data.sort_values(by=col, ascending=(col in ["D"])).reset_index()
# print(sorted_data["Player"])
player_rank = sorted_data.index[sorted_data['Player'] == player].tolist()[0] + 1
player_rankings.append(player_rank)
rankings_dict[player] = mean(player_rankings)
ranks[role] = rankings_dict
return ranks
percentile_ranks = rankings(role_rank_test, relevant_cols, positions)
# convert the float 'ranks' to actual ranks from 1 to 10/11
for role, players in percentile_ranks.items():
# sort the players based on their scores in descending order
sorted_players = sorted(players, key=players.get, reverse=False)
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted list
for i, player in enumerate(sorted_players):
rankings[player] = i + 1
# replace the original scores with the rankings
percentile_ranks[role] = rankings
def ensemble_rankings(args, ensemble_models, neural_net_models):
role_rank_test = args[0]
releveant_cols = args[1]
positions = args[2]
ranks = {}
for role in positions:
ensemble_model = ensemble_models[role]
relevant = releveant_cols[positions.index(role)]
rankings_dict = {}
players = role_rank_test[positions.index(role)]["Player"]
temp_data = role_rank_test[positions.index(role)][relevant]
# augmenting with the nn stack
temp_data_augmented = temp_data
for key, value in neural_net_models.items(): # key is the model name, value is the dictionary
role_fittings_for_nn = value
# role_fittings_for_nn is a dictionary with the role as the key
# and the value is the corresponding model's name in disk
# get the pre-trained neural model for the current role
model_addr = role_fittings_for_nn[role]
model = load_model(model_addr)
# get the output of the keras neural model on the training data
nn_output = model.predict(temp_data, verbose=0)
# add the neural network output as a feature to the original training data
temp_data_augmented = np.hstack((temp_data_augmented, nn_output))
# predict with ensemble model
predictions = ensemble_model.predict(temp_data_augmented)
rankings_dict = {player: rank for player, rank in zip(players, predictions)}
sorted_players = sorted(rankings_dict, key=rankings_dict.get, reverse=True)
rankings = {}
for i, player in enumerate(sorted_players):
rankings[player] = i + 1
ranks[role] = rankings
return ranks
from keras.models import load_model
from joblib import dump, load
testing_ensemble_args = [role_rank_test, relevant_cols, positions]
os.chdir(os.path.join(og_dir, 'model_files'))
top_ensem = load('Stacked_Ensemble_Top.joblib')
sup_ensem = load('Stacked_Ensemble_Support.joblib')
adc_ensem = load('Stacked_Ensemble_ADC.joblib')
mid_ensem = load('Stacked_Ensemble_Middle.joblib')
jgl_ensem = load('Stacked_Ensemble_Jungle.joblib')
ensemble_models = {
'Top': top_ensem,
'Support': sup_ensem,
'ADC': adc_ensem,
'Middle': mid_ensem,
'Jungle': jgl_ensem
}
nn_scaled = {'Basic LSTM': {'Support': 'Basic_LSTM_Support.keras',
'Jungle': 'Basic_LSTM_Jungle.keras',
'Top': 'Basic_LSTM_Top.keras',
'Middle': 'Basic_LSTM_Middle.keras',
'ADC': 'Basic_LSTM_ADC.keras'},
'Basic LSTM with sigmoid acv fn': {'Support': 'Basic_LSTM_with_sigmoid_acv_fn_Support.keras',
'Jungle': 'Basic_LSTM_with_sigmoid_acv_fn_Jungle.keras',
'Top': 'Basic_LSTM_with_sigmoid_acv_fn_Top.keras',
'Middle': 'Basic_LSTM_with_sigmoid_acv_fn_Middle.keras',
'ADC': 'Basic_LSTM_with_sigmoid_acv_fn_ADC.keras'},
'Stacked LSTM with dropout': {'Support': 'Stacked_LSTM_with_dropout_Support.keras',
'Jungle': 'Stacked_LSTM_with_dropout_Jungle.keras',
'Top': 'Stacked_LSTM_with_dropout_Top.keras',
'Middle': 'Stacked_LSTM_with_dropout_Middle.keras',
'ADC': 'Stacked_LSTM_with_dropout_ADC.keras'},
'Convolution model': {'Support': 'Convolution_model_Support.keras',
'Jungle': 'Convolution_model_Jungle.keras',
'Top': 'Convolution_model_Top.keras',
'Middle': 'Convolution_model_Middle.keras',
'ADC': 'Convolution_model_ADC.keras'},
'RNN Model': {'Support': 'RNN_Model_Support.keras',
'Jungle': 'RNN_Model_Jungle.keras',
'Top': 'RNN_Model_Top.keras',
'Middle': 'RNN_Model_Middle.keras',
'ADC': 'RNN_Model_ADC.keras'}}
ensemble_ranks = ensemble_rankings(testing_ensemble_args, ensemble_models, nn_scaled)
# now to get the MVP ranks
mvp_ranks = {}
for role in positions:
temp_players = role_rank_test[positions.index(role)][["Player", "MVP"]]
temp_players = temp_players.sort_values(by="MVP", ascending=False).reset_index()
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted db
for i, row in temp_players.iterrows():
rankings[row["Player"]] = i + 1
# replace the original scores with the rankings
mvp_ranks[role] = rankings
# combine the three ranks into one
final_evaluation = {}
for role in positions:
mvp_rankings = mvp_ranks[role]
ensemble_rankings = ensemble_ranks[role]
percentile_rankings = percentile_ranks[role]
# Combine the rankings using a suitable method, such as averaging
combined_rankings = {}
for player in mvp_rankings:
# Compute the average rank of the player across the three structures
avg_rank = (mvp_rankings[player] + ensemble_rankings[player] + percentile_rankings[player]) / 3
# Add the player and their average rank to the combined rankings
combined_rankings[player] = avg_rank
sorted_ranks = sorted(combined_rankings, key=combined_rankings.get, reverse=False)
rankings = {}
for i, player in enumerate(sorted_ranks):
rankings[player] = i + 1
# Store the combined rankings for the position in the final_evaluation dictionary
final_evaluation[role] = rankings
final_evaluation
{'Top': {'BrokenBlade': 1,
'Alphari': 2,
'Odoamne': 3,
'JNX': 4,
'Armut': 5,
'Finn': 6,
'Wunder': 7,
'Adam': 8,
'HiRit': 9,
'WhiteKnight': 10},
'Jungle': {'Elyoya': 1,
'Cinkrof': 2,
'Razork': 3,
'Malrang': 4,
'Markoon': 5,
'Selfmade': 6,
'Jankos': 7,
'Zanzarah': 8,
'Gilius': 9,
'Shlatan': 10},
'Middle': {'Larssen': 1,
'Vetheo': 2,
'Humanoid': 3,
'Perkz': 4,
'Caps': 5,
'Sertuss': 6,
'Dajor': 7,
'Nukeduck': 8,
'Reeker': 9,
'nuc': 10},
'ADC': {'Comp': 1,
'Neon': 2,
'Upset': 3,
'Patrik': 4,
'Flakked': 5,
'Jezu': 6,
'Kobbe': 7,
'Carzzy': 8,
'UNF0RGIVEN': 9,
'xMatty': 10},
'Support': {'Hylissang': 1,
'Trymbi': 2,
'Mikyx': 3,
'Targamas': 4,
'promisq': 5,
'Kaiser': 6,
'LIMIT': 7,
'Treatz': 8,
'Advienne': 9,
'Mersa': 10,
'Labrov': 11}}
# Working on polar graphs for Given player vs Rank 1 Player or any given Player
import plotly.graph_objects as go
# data for the radar chart
player_name = "promisq" #promisq more internationals than <x>
comparison = 1 # rank of the player to be compared with, default 1
comparison_name = "" # name of the player. ideally, feed either or
# get the row for the player from the DataFrame
player_row = player_data[player_data["Player"] == player_name]
player_role = player_row["Pos"].iloc[0]
polar_relevant = relevant_cols[positions.index(player_role)]
for key, value in final_evaluation[player_role].items():
if value == comparison:
comparison_name = key
comaprison_row = player_data[player_data["Player"] == comparison_name]
player_percentiles = []
comparison_percentiles = []
max_percentiles = [1 for col in polar_relevant]
# Get the percentiles for the player's role
role_data = player_data[player_data["Pos"] == player_role]
for col in polar_relevant:
max_val = role_data[col].max()
player_val = player_row[col].iloc[0]
player_percentiles.append(player_val / max_val)
comp_val = comaprison_row[col].iloc[0]
comparison_percentiles.append(comp_val / max_val)
# get the list of all players with the same "Pos"
# For col in relevant cols ->
# sort them by col, then take greatest value in the given col and value of the given player
# store the percentage values for given player (basically just the ratio)
# do the same for the comparison player, and store in the separate list
fig = go.Figure()
# add the max values to set the background
fig.add_trace(go.Scatterpolar(
r=max_percentiles,
theta=list(polar_relevant),
fill='toself',
name='Max Value amongst Players'
))
# add the player's data to the chart
fig.add_trace(go.Scatterpolar(
r=player_percentiles,
theta=list(polar_relevant),
fill='toself',
name='Player Scores for ' + player_name
))
# add the comparison percentiles to the chart
fig.add_trace(go.Scatterpolar(
r=comparison_percentiles,
theta=list(polar_relevant),
fill='toself',
name='Scores for rank ' + str(comparison) + ' : ' + comparison_name
))
# customize the layout of the chart
fig.update_layout(
polar=dict(
radialaxis=dict(
visible=True,
range=[0, 1]
)
),
showlegend=True
)
# show the chart
fig.show(renderer='notebook')
Real Ranks :
First : Odo, Malrang, Vethro, Upset, Hyli
Second : BB, Jankos (Aware), Umanoid, Comp, Trymbi
Third : Wunder (xdd),Elyoya, Larssen, Patrik, Targamas
Our Ranks :
First : BB, Elyoya, Larssen, Comp, Hyli
Second : Alphari, Cinkrof, Vetheo, Neon, Trymbi
Third : Odo, Razork, Umanoid, Upset, MickeyXdd
Top : Odo, BB check. Wunder 7th OMEGALUL
Jgl : Elyoya check. Malrang 4th, Juankos 7th xddDespair
Mid : Larssen, Vetheo, Umanoid check, but Umanoid > vetheo/larssen
Bot : Upset was upset by comp and neon. Patrik 4th
Supp : Hyli kingdom. Trymbi correct, Targamas 4th, mikyxdd replaces
# now for NA, gotta make it fast, they have a plane to catch
# now ranking the Spring 2023 roster data
os.chdir(os.path.join(og_dir, "secret_regions_test"))
player_data = pd.read_csv('LCS 2023 Spring.csv')
mvp_data = pd.read_csv('lcs_mvp.csv')
os.chdir(os.path.join(og_dir, "model_files"))
# create a new column called "MVP" in the player_data dataframe
player_data["MVP"] = 0
# iterate over each row in the MVP data dataframe
for index, row in mvp_data.iterrows():
# check if the player's name exists in the player_data dataframe
if row["Player"] in player_data["Player"].values:
# if so, find the row with the player's name and update the "MVP" column with the MVP points
player_data.loc[player_data["Player"] == row["Player"], "MVP"] = row["Points"]
player_data['Year'] = "2023"
player_data['Season'] = "Spring"
exclude = ['Player', 'Team', 'Pos', 'Year', 'Season']
incldue = [col for col in player_data.columns if col not in exclude]
for cols in incldue:
for idx, val in player_data[cols].items():
if str(val).endswith("%"):
player_data.at[idx, cols] = str(val.strip("%"))
player_data[incldue] = player_data[incldue].astype('float64')
rank_test = scale_split(player_data)
rank_test = rank_test.dropna(axis=1)
rank_test_vals = rank_test.select_dtypes(include='number')
rank_test_vals = rank_test_vals.drop(['GP', 'MVP'], axis=1)
rank_test_labels = rank_test.select_dtypes(exclude='number')
rank_test_labels = pd.concat([rank_test_labels, rank_test[['GP', 'MVP']]], axis=1)
role_rank_test = []
role_rank_test_labels = []
role_rank_test_vals = []
# generating 5 sets of data for players in each role
for position in positions:
role_rank_test.append(rank_test[rank_test['Pos'] == position])
role_rank_test_labels.append(rank_test_labels[rank_test_labels['Pos'] == position])
role_rank_test_vals.append(rank_test_vals[rank_test_labels['Pos'] == position])
role_rank_test[positions.index("ADC")].sort_values(by=['KDA', 'W%', 'DMG%'], ascending=False).head()
| Player | Team | Pos | GP | W% | CTR% | K | D | A | KDA | ... | D%P15 | EGPM | GOLD% | STL | WPM | CWPM | WCPM | MVP | Year | Season | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | Berserker | Cloud9 | ADC | 0.947368 | 0.79 | 0.42 | 0.836538 | 0.253731 | 0.489474 | 0.933333 | ... | 0.807432 | 0.963504 | 0.946341 | 0.0 | 0.159664 | 0.282051 | 0.551020 | 0.500000 | 2023 | Spring |
| 37 | Prince | FlyQuest | ADC | 0.947368 | 0.74 | 0.63 | 0.971154 | 0.447761 | 0.389474 | 0.504762 | ... | 0.922297 | 1.000000 | 0.985366 | 0.0 | 0.243697 | 0.307692 | 0.775510 | 0.833333 | 2023 | Spring |
| 18 | FBI | Evil Geniuses | ADC | 0.947368 | 0.53 | 0.53 | 0.903846 | 0.522388 | 0.478947 | 0.457143 | ... | 0.952703 | 0.879562 | 0.941463 | 0.0 | 0.134454 | 0.230769 | 0.571429 | 0.166667 | 2023 | Spring |
| 32 | Luger | Counter Logic Gaming | ADC | 0.947368 | 0.53 | 0.58 | 0.673077 | 0.447761 | 0.410526 | 0.428571 | ... | 0.658784 | 0.813869 | 0.868293 | 0.2 | 0.033613 | 0.076923 | 0.632653 | 0.333333 | 2023 | Spring |
| 15 | Doublelift | 100 Thieves | ADC | 1.000000 | 0.60 | 0.55 | 1.000000 | 0.686567 | 0.531579 | 0.380952 | ... | 0.956081 | 0.923358 | 0.995122 | 0.0 | 0.109244 | 0.179487 | 0.775510 | 1.000000 | 2023 | Spring |
5 rows × 31 columns
percentile_ranks = rankings(role_rank_test, relevant_cols, positions)
# convert the float 'ranks' to actual ranks from 1 to 10/11
for role, players in percentile_ranks.items():
# sort the players based on their scores in descending order
sorted_players = sorted(players, key=players.get, reverse=False)
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted list
for i, player in enumerate(sorted_players):
rankings[player] = i + 1
# replace the original scores with the rankings
percentile_ranks[role] = rankings
testing_ensemble_args = [role_rank_test, relevant_cols, positions]
ensemble_ranks = ensemble_rankings(testing_ensemble_args, ensemble_models, nn_scaled)
# now to get the MVP ranks
mvp_ranks = {}
for role in positions:
temp_players = role_rank_test[positions.index(role)][["Player", "MVP"]]
temp_players = temp_players.sort_values(by="MVP", ascending=False).reset_index()
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted db
for i, row in temp_players.iterrows():
rankings[row["Player"]] = i + 1
# replace the original scores with the rankings
mvp_ranks[role] = rankings
# combine the three ranks into one
final_evaluation = {}
for role in positions:
mvp_rankings = mvp_ranks[role]
ensemble_rankings = ensemble_ranks[role]
percentile_rankings = percentile_ranks[role]
# Combine the rankings using a suitable method, such as averaging
combined_rankings = {}
for player in mvp_rankings:
# Compute the average rank of the player across the three structures
avg_rank = (mvp_rankings[player] + ensemble_rankings[player] + percentile_rankings[player]) / 3
# Add the player and their average rank to the combined rankings
combined_rankings[player] = avg_rank
sorted_ranks = sorted(combined_rankings, key=combined_rankings.get, reverse=False)
rankings = {}
for i, player in enumerate(sorted_ranks):
rankings[player] = i + 1
# Store the combined rankings for the position in the final_evaluation dictionary
final_evaluation[role] = rankings
final_evaluation
{'Top': {'Fudge': 1,
'Dhokla': 2,
'Summit': 3,
'Impact': 4,
'Ssumday': 5,
'Armut': 6,
'Revenge': 7,
'Hauntzer': 8,
'Solo': 9,
'Tenacity': 10,
'Licorice': 11},
'Jungle': {'Spica': 1,
'Blaber': 2,
'Pyosik': 3,
'Closer': 4,
'Inspired': 5,
'River': 6,
'Contractz': 7,
'Bugi': 8,
'Kenvi': 9,
'Santorin': 10},
'Middle': {'VicLa': 1,
'Gori': 2,
'EMENES': 3,
'jojopyun': 4,
'Palafox': 5,
'Maple': 6,
'Bjergsen': 7,
'Jensen': 8,
'Haeri': 9,
'ry0ma': 10,
'Bolulu': 11,
'Ablazeolive': 12,
'Diplex': 13,
'Young': 14},
'ADC': {'Doublelift': 1,
'Prince': 2,
'Berserker': 3,
'FBI': 4,
'WildTurtle': 5,
'Yeon': 6,
'Luger': 7,
'Stixxay': 8,
'Neo': 9,
'Tactical': 10,
'Tomo': 11,
'Spawn': 12},
'Support': {'huhi': 1,
'Busio': 2,
'CoreJJ': 3,
'Vulcan': 4,
'Fleshy': 5,
'Zven': 6,
'Chime': 7,
'Winsome': 8,
'Poome': 9,
'Eyla': 10,
'Biofrost': 11,
'IgNar': 12}}
Real ranks :
First : Fudge factor, Crabber, Gori, Zerker, Vulcan
Second : Impact, Spica, EMENES, Prince xdd, Zven
Third : Ssumday, Inspired, VicLa, DL, Huhi
Model Ranks :
First : Fudge factor, Spica, VicLa, DL, Huhi
Second : Big Dhokes, Crabber, Gori, Prince, Busio
Third : Summit, World Champ Pyosik, EMENES, Zerker, CoreJJ
Top has big chnages, Impact Ssumday are 4-5
Jungle -> Inspired comes 5th
Mid -> Same 3, but order
ADC -> same 3, order
Supp -> Vulcan is 4th, Zven is 6th
#Quick LPL test, but a lot of features are unavailable for their data
# FB%, GD@10, CSD@10 changed to EGPM for GD@10 and CPSPM for CSD@10. FB% is not used
relevant_lpls = [['K', 'A', 'KDA', 'KP', 'KS%', 'EGPM', 'CSPM', 'DMG%', 'GOLD%', 'WPM'],
['K', 'A', 'KDA', 'KP', 'KS%', 'DTH%', 'EGPM', 'CSPM', 'WPM', 'WCPM'],
['K', 'D', 'A', 'KDA', 'KS%', 'DTH%', 'EGPM', 'CSPM', 'DMG%', 'WPM'],
['K', 'D', 'A', 'KP', 'CSPM', 'DMG%', 'GOLD%', 'WPM', 'CWPM', 'WCPM'],
['K', 'D', 'A', 'KDA', 'KS%', 'CSPM', 'DMG%', 'GOLD%', 'WPM', 'CWPM']]
# now ranking the Spring 2023 roster data
os.chdir(os.path.join(og_dir, "secret_regions_test"))
player_data = pd.read_csv('LPL 2023 Spring.csv')
mvp_data = pd.read_csv('lpl_mvp.csv')
os.chdir(os.path.join(og_dir, "model_files"))
# create a new column called "MVP" in the player_data dataframe
player_data["MVP"] = 0
# iterate over each row in the MVP data dataframe
for index, row in mvp_data.iterrows():
# check if the player's name exists in the player_data dataframe
if row["Player"] in player_data["Player"].values:
# if so, find the row with the player's name and update the "MVP" column with the MVP points
player_data.loc[player_data["Player"] == row["Player"], "MVP"] = row["Points"]
player_data['Year'] = "2023"
player_data['Season'] = "Spring"
exclude = ['Player', 'Team', 'Pos', 'Year', 'Season']
incldue = [col for col in player_data.columns if col not in exclude]
for cols in incldue:
for idx, val in player_data[cols].items():
if str(val).endswith("%"):
player_data.at[idx, cols] = str(val.strip("%"))
player_data[incldue] = player_data[incldue].astype('float64')
rank_test = scale_split(player_data)
rank_test = rank_test.dropna(axis=1)
rank_test_vals = rank_test.select_dtypes(include='number')
rank_test_vals = rank_test_vals.drop(['GP', 'MVP'], axis=1)
rank_test_labels = rank_test.select_dtypes(exclude='number')
rank_test_labels = pd.concat([rank_test_labels, rank_test[['GP', 'MVP']]], axis=1)
role_rank_test = []
role_rank_test_labels = []
role_rank_test_vals = []
# generating 5 sets of data for players in each role
for position in positions:
role_rank_test.append(rank_test[rank_test['Pos'] == position])
role_rank_test_labels.append(rank_test_labels[rank_test_labels['Pos'] == position])
role_rank_test_vals.append(rank_test_vals[rank_test_labels['Pos'] == position])
role_rank_test[positions.index("ADC")].sort_values(by=['KDA', 'W%', 'DMG%'], ascending=False).head()
| Player | Team | Pos | GP | W% | CTR% | K | D | A | KDA | ... | DPM | DMG% | EGPM | GOLD% | WPM | CWPM | WCPM | MVP | Year | Season | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 72 | Ruler | JD Gaming | ADC | 0.853659 | 0.78 | 0.47 | 0.773148 | 0.246575 | 0.434679 | 1.000000 | ... | 0.784441 | 0.711462 | 1.000000 | 0.940 | 0.197917 | 0.313725 | 0.750000 | 0.529412 | 2023 | Spring |
| 50 | Light | Weibo Gaming | ADC | 0.926829 | 0.64 | 0.54 | 0.814815 | 0.390411 | 0.453682 | 0.646341 | ... | 0.784441 | 0.802372 | 0.935361 | 0.960 | 0.140625 | 0.117647 | 0.613636 | 0.176471 | 2023 | Spring |
| 51 | LP | LNG Esports | ADC | 0.926829 | 0.72 | 0.38 | 0.939815 | 0.534247 | 0.548694 | 0.560976 | ... | 0.867099 | 0.830040 | 0.897338 | 0.895 | 0.166667 | 0.156863 | 0.727273 | 0.117647 | 2023 | Spring |
| 37 | huanfeng | ThunderTalk Gaming | ADC | 0.853659 | 0.50 | 0.61 | 0.611111 | 0.342466 | 0.334917 | 0.536585 | ... | 0.658023 | 0.723320 | 0.828897 | 0.900 | 0.177083 | 0.196078 | 0.522727 | 0.176471 | 2023 | Spring |
| 22 | Elk | Bilibili Gaming | ADC | 1.000000 | 0.60 | 0.45 | 1.000000 | 0.609589 | 0.501188 | 0.475610 | ... | 1.000000 | 1.000000 | 0.950570 | 0.975 | 0.156250 | 0.156863 | 0.727273 | 0.352941 | 2023 | Spring |
5 rows × 24 columns
percentile_ranks = rankings(role_rank_test, relevant_lpls, positions)
# convert the float 'ranks' to actual ranks from 1 to 10/11
for role, players in percentile_ranks.items():
# sort the players based on their scores in descending order
sorted_players = sorted(players, key=players.get, reverse=False)
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted list
for i, player in enumerate(sorted_players):
rankings[player] = i + 1
# replace the original scores with the rankings
percentile_ranks[role] = rankings
testing_ensemble_args = [role_rank_test, relevant_lpls, positions]
ensemble_ranks = ensemble_rankings(testing_ensemble_args, ensemble_models, nn_scaled)
# now to get the MVP ranks
mvp_ranks = {}
for role in positions:
temp_players = role_rank_test[positions.index(role)][["Player", "MVP"]]
temp_players = temp_players.sort_values(by="MVP", ascending=False).reset_index()
# create a new dictionary to store the rankings
rankings = {}
# assign rankings to each player based on their position in the sorted db
for i, row in temp_players.iterrows():
rankings[row["Player"]] = i + 1
# replace the original scores with the rankings
mvp_ranks[role] = rankings
# combine the three ranks into one
final_evaluation = {}
for role in positions:
mvp_rankings = mvp_ranks[role]
ensemble_rankings = ensemble_ranks[role]
percentile_rankings = percentile_ranks[role]
# Combine the rankings using a suitable method, such as averaging
combined_rankings = {}
for player in mvp_rankings:
# Compute the average rank of the player across the three structures
avg_rank = (mvp_rankings[player] + ensemble_rankings[player] + percentile_rankings[player]) / 3
# Add the player and their average rank to the combined rankings
combined_rankings[player] = avg_rank
sorted_ranks = sorted(combined_rankings, key=combined_rankings.get, reverse=False)
rankings = {}
for i, player in enumerate(sorted_ranks):
rankings[player] = i + 1
# Store the combined rankings for the position in the final_evaluation dictionary
final_evaluation[role] = rankings
final_evaluation
{'Top': {'shanji': 1,
'Ale': 2,
'YSKM': 3,
'Zika': 4,
'TheShy': 5,
'Breathe': 6,
'Bin': 7,
'Xiaoxu': 8,
'369': 9,
'Invincible': 10,
'Zdz': 11,
'Wayward': 12,
'Cube': 13,
'Biubiu': 14,
'Qingtian': 15,
'Hery': 16,
'neny': 17,
'HOYA': 18,
'Xiaolaohu': 19,
'Rich': 20,
'fearness': 21},
'Jungle': {'Kanavi': 1,
'Jiejie': 2,
'Karsa': 3,
'Tarzan': 4,
'Leyan': 5,
'Beichuan': 6,
'Tian': 7,
'Heng': 8,
'Wei': 9,
'Ning': 10,
'Xun': 11,
'Aki': 12,
'Xiaohao': 13,
'Meteor': 14,
'XLB': 15,
'shad0w': 16,
'haoye': 17,
'H4cker': 18,
'gideon': 19},
'Middle': {'Scout': 1,
'Xiaohu': 2,
'Rookie': 3,
'Shanks': 4,
'FoFo': 5,
'knight': 6,
'Yagao': 7,
'Creme': 8,
'Care': 9,
'ucal': 10,
'pinz': 11,
'Angel': 12,
'Strive': 13,
'neny': 14,
'Dove': 15,
'Qing': 16,
'haichao': 17,
'Pout': 18,
'Forge': 19,
'Dream': 20,
'Harder': 21,
'xqw': 22,
'Tangyuan': 23},
'ADC': {'Elk': 1,
'JackeyLove': 2,
'Ruler': 3,
'Able': 4,
'LP': 5,
'GALA': 6,
'Hope': 7,
'Light': 8,
'Doggo': 9,
'Ahn': 10,
'Photic': 11,
'Lwx': 12,
'Leave': 13,
'Betty': 14,
'Assum': 15,
'Lpc': 16,
'huanfeng': 17},
'Support': {'Iwandy': 1,
'Wink': 2,
'Missing': 3,
'Zhuo': 4,
'ON': 5,
'Meiko': 6,
'Crisp': 7,
'Jinjiao': 8,
'ppgod': 9,
'Mark': 10,
'Ming': 11,
'Hang': 12,
'yaoyao': 13,
'Baolan': 14,
'XinLiu': 15,
'Lele': 16,
'QiuQiu': 17,
'Bunny': 18,
'Southwind': 19,
'SwordArt': 20,
'Jerry': 21,
'bkr': 22}}
Real Ranks :
First : 369, JieJie, Scout, Ruler, Meiko
Second : Ale, Kanavi, Knight, Elk, Missing
Thrid : Shanji, Tarzan, FoFo, Leave, Hang
Model Ranks :
First : Shanji, Kanavi, Scout, Elk, Iwandy
Second : Ale, JieJie, Xiaohu, JKL, Wink
Third : YSKM, Karsa, Cookie, Ruler, Missing
top -> 369 rolled a 9 :( TheSHY is 5th even after all that inting, my man
jgl -> Tarzan close 4th
Mid -> fofo, knight 5-6, shanks on 4
ADC -> xdd JKL, dear god leave is 13th??
Supp -> Meiko on 6, Hang on 12th?
(keep in mind its the model doing this)